package com.yc.chatroom.server;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.lang.NonNull;
import com.yc.chatroom.common.Constant;
import com.yc.chatroom.common.dto.BaseDto;
import com.yc.chatroom.common.dto.ResultDto;
import com.yc.chatroom.common.dto.ShowMsgDto;
import com.yc.chatroom.server.pojo.LoginStatus;
import com.yc.chatroom.server.pojo.SessionInfo;
import com.yc.chatroom.server.pojo.po.UserPo;

import io.netty.channel.ChannelHandlerContext;

public class ChannelOnline {
    //所有的链接
//    private Map<Integer, ChannelInfo> channelMap = new HashMap<>();
    
    private Map<ChannelHandlerContext, SessionInfo> channels = new HashMap<>();
    
    
    public void loginSuccess(@NonNull UserPo userPo, @NonNull ChannelHandlerContext chanel) {
    	SessionInfo sessionInfo = channels.get(chanel);
    	if (null == sessionInfo) {
    		//查询数据库，判断用户的当前状态：如果是登录状态，则说明map中已经存在一个连接（重复登录）；如果是没登录，则直接添加一个连接
    		SessionInfo sessionInfoNew = new SessionInfo(userPo.getUserId(), userPo.getUserAccount(), 
    				userPo.getUserName(), LoginStatus.LOGIN, new Date().getTime());
            channels.put(chanel, sessionInfoNew);
    		if (LoginStatus.LOGIN.getId().equals(userPo.getUserOnlineStatus())) {
    			//重复登录:另起线程 找到那个连接（正常应该把连接序列化到本地，直接拿到），然后通知他一下，然后断掉连接
    			logoutOldChannel(userPo.getUserId());
    		}

    	} else {//同一个连接已经存在：更新map，更新数据库
    		sessionInfo.setLoginStatus(LoginStatus.LOGIN);
    		sessionInfo.setUserAccount(userPo.getUserAccount());
    		sessionInfo.setUserId(userPo.getUserId());
    		sessionInfo.setUserName(userPo.getUserName());
    		sessionInfo.setStatusModifyTime(new Date().getTime());
    	}
    }
    
    public void loginFall(@NonNull ChannelHandlerContext chanel) {
    	SessionInfo s = new SessionInfo();
    	s.setLoginStatus(LoginStatus.READY);
    	s.setStatusModifyTime(new Date().getTime());
    	channels.put(chanel, s);
    }
    
    /**
     * 根据userId找到连接，并通知，然后关闭，最后删除
     * @param userId
     */
    private void logoutOldChannel(Integer userId) {
    	new Thread(() -> {
    		ChannelHandlerContext logoutChannel = null;
    		for (Map.Entry<ChannelHandlerContext, SessionInfo> itemChanel : channels.entrySet()) {
    			if (itemChanel.getValue().getUserId().equals(userId)) {
    				logoutChannel = itemChanel.getKey();
    				break;
    			}
    		}
    		
    		channels.remove(logoutChannel);//先删除连接（有可能后面因为关闭操作而变的不一样）
    		sendMsg(logoutChannel, "你已经在其他地方登陆，如果不是自己的操作，请及时更新密码。");
			try {
                Thread.sleep(2000);//2秒后删除连接
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
			logoutChannel.close();//关闭连接
    		
    	}).start();
    	
    }

//    //添加一个链接
//    public void add(Integer userId, ChannelHandlerContext chanel, Integer functionCode, Integer loginStatus) {
//        //判断是否已经有连接，
//        // 如果有并且连接已经改变
//        //  就给那个连接发一条消息：你已经在其他地方登陆，如果不是自己的操作，请及时更新密码。然后断开连接, 再赋值新连接
//        // 如果有连接但连接还是同一条，那么直接结束
//        // 如果没有，则添加
//    	ChannelInfo channelInfo = channelMap.get(userId);
//        if (null == channelInfo) {
//            channelMap.put(userId, new ChannelInfo(chanel, functionCode, loginStatus));
//        } else {
//        	ChannelHandlerContext channelOld = channelInfo.getChannel();
//            if (!channelOld.equals(chanel)) {
//                new Thread(() -> {
//                    sendMsg(channelOld, "你已经在其他地方登陆，如果不是自己的操作，请及时更新密码。");
//                    try {
//                        Thread.sleep(2000);//三秒后删除连接
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    channelOld.close();
//                    channelMap.put(userId, new ChannelInfo(chanel, functionCode, loginStatus));
//                }).start();
//
//            } else {
//                return;
//            }
//        }
//    }

    /**
     * 校验连接
     * @param userId
     * @param channel
     * @return
     */
    public ResultDto check(ChannelHandlerContext channel) {
        ResultDto res = new ResultDto();
        SessionInfo sessionInfo = channels.get(channel);
        if (null == sessionInfo || !LoginStatus.LOGIN.equals(sessionInfo.getLoginStatus())) {
            res.setCode(Constant.RESULT_CODE_SESSION_EXPIRED);
            res.setMsg("未登陆");
            return res;
        }
        return res;
    }

    /**
     * 给所有在线用户发消息
     * @param msgDto
     */
    public void sendShowMsgForAll(ShowMsgDto showMsgDto) {
    	
    	channels.forEach((k, v) -> {
            if (LoginStatus.LOGIN.equals(v.getLoginStatus())) {
            	if (!v.getUserId().equals(showMsgDto.getUserId())) {
            		k.writeAndFlush(showMsgDto);
            	} else {//给发消息人本人回显消息，消息稍有变化
            		ShowMsgDto smd = new ShowMsgDto();
            		smd.setMe(true);
            		smd.setMessage(showMsgDto.getMessage());
            		smd.setSendTime(showMsgDto.getSendTime());
            		smd.setUserName(showMsgDto.getUserName());
            		k.writeAndFlush(smd);
            	}
               
            }
        });
    }
    
    /**
     * 给所有人发普通消息
     * @param baseDto
     */
    public void sendCommonMsgForAll(BaseDto baseDto) {
    	
    	channels.forEach((k, v) -> {
            if (LoginStatus.LOGIN.equals(v.getLoginStatus())) {
            	k.writeAndFlush(baseDto);
            }
        });
    }
    
    public SessionInfo getSessionInfo(ChannelHandlerContext channel) {
    	return channels.get(channel);
    }

    //删除一个链接
//    public void remove(String userId) {
//        channelMap.remove(userId);
//    }
    public void remove(ChannelHandlerContext channel) {
    	channels.remove(channel);
    }

    public void sendMsg(ChannelHandlerContext channel, String msg) {
        ResultDto res = new ResultDto();
        res.setCode(Constant.RESULT_CODE_SYSTEM_NOTIFY);
        res.setMsg(msg);
        channel.writeAndFlush(res);
    }

}
